package com.jh.paymentchannel.service;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.jh.paymentchannel.pojo.BankInfoCode;
import com.jh.paymentchannel.pojo.JFMQuickBindCard;
import com.jh.paymentchannel.pojo.JFQuickRegister;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.jh.paymentchannel.business.BranchbankBussiness;
import com.jh.paymentchannel.business.TopupPayChannelBusiness;
import com.jh.paymentchannel.util.Util;
import com.jh.paymentchannel.util.jifuquick.AES;
import com.jh.paymentchannel.util.jifuquick.Base64;
import com.jh.paymentchannel.util.jifuquick.PayGetToken;
import com.jh.paymentchannel.util.jifuquick.TokenConstants;

import net.sf.json.JSONObject;

@Service
public class JFMQuickTopupRequest implements TopupRequest {

	private static final Logger log = LoggerFactory.getLogger(JFMQuickTopupRequest.class);

	@Autowired
	private TopupPayChannelBusiness topupPayChannelBusiness;

	@Autowired
	private BranchbankBussiness branchbankBussiness;

	@Autowired
	private Util util;

	@Value("${payment.ipAddress}")
	private String ipAddress;
	
	// 服务商编号
	@Value("${jfm.org_no}")
	private String partnerNo;
	
	@Value("${jfm.url}")
	private String JFMurl;

	private static final Charset UTF_8 = StandardCharsets.UTF_8;
	
	private String Key = "00000000000000000000000000000000";

	private String rateCode = "1000005";

	private String capAmount = "999999";

	@Override
	public Map<String, String> topupRequest(HttpServletRequest request, String amount, String ordercode,
			String orderdesc, String extra, String notifyurl, String returnurl, String channelParam) throws Exception {
		log.info("=========ipAddress=========" + ipAddress);
		Map<String, String> map = new HashMap<String, String>();
		//获取用户的userid
		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("transactionclear", "error url request!");
		String url = uri.toString() + "/v1.0/transactionclear/payment/query/ordercode";
		MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<String, String>();
		requestEntity.add("order_code", ordercode);
		String result = restTemplate.postForObject(url, requestEntity, String.class);
		log.info("=========RESULT=========" + result);
		JSONObject jsonObject;
		JSONObject resultObj;
		try {
			jsonObject = JSONObject.fromObject(result);
			resultObj = jsonObject.getJSONObject("result");
		} catch (Exception e) {
			log.error("查询订单信息出错");
			map.put("resp_code", "failed");
			map.put("channel_type", "jf");
			map.put("resp_message", "没有该订单信息");
			return map;
		}
		String realamount = resultObj.getString("realAmount");
		String userid = resultObj.getString("userid");
		// 费率
		String rate = resultObj.getString("rate");
		// 额外费率
		String extraFee = resultObj.getString("extraFee");
		// 银行卡
		String bankCard = resultObj.getString("bankcard");

		restTemplate = new RestTemplate();
		uri = util.getServiceUrl("user", "error url request!");
		url = uri.toString() + "/v1.0/user/bank/default/userid";
		requestEntity = new LinkedMultiValueMap<String, String>();
		requestEntity.add("user_id", userid);
		result = restTemplate.postForObject(url, requestEntity, String.class);
		log.info("=========RESULT=========" + result);
		try {
			jsonObject = JSONObject.fromObject(result);
			resultObj = jsonObject.getJSONObject("result");
		} catch (Exception e) {
			log.error("查询默认结算卡出错");
			map.put("resp_code", "failed");
			map.put("channel_type", "jf");
			map.put("resp_message", "查询默认结算卡有误");
			return map;
		}
		if (resultObj.isNullObject()) {
			map.put("resp_code", "failed");
			map.put("channel_type", "jf");
			map.put("resp_message", "没有结算卡");
			return map;
		}
		String cardNo = resultObj.getString("cardNo");
		String userName = resultObj.getString("userName");
		//身份证号
		String idcard = resultObj.getString("idcard");
		String phone = resultObj.getString("phone");
		//开户行所在省
		String provinceOfBank = resultObj.getString("province");
		log.info("provinceOfBank" + provinceOfBank);
		//开户行所在市
		String cityOfBank = resultObj.getString("city");
		log.info("cityOfBank" + cityOfBank);
		//银行名称
		String bankName = resultObj.getString("bankName");
		//支行名称
		String bankBranchName = resultObj.getString("bankBranchName");
		String cardType = resultObj.getString("cardType");
		// 支行联行号
		String bankBranchNo = null;
		try {
			BankInfoCode bankInfoCodeByBankName = topupPayChannelBusiness.getBankInfoCodeByBankName(bankBranchName);
			bankBranchNo = bankInfoCodeByBankName.getBankNo();
		} catch (Exception e) {
			log.error("支行联行号查询有误=========" + e);
			map.put("resp_code", "failed");
			map.put("channel_type", "jf");
			map.put("resp_message", "查询支行联行号有误");
			return map;
		}
		log.info("bankBranchNo" + bankBranchNo);

		//获取银行卡信息
		restTemplate=new RestTemplate();
		uri = util.getServiceUrl("user", "error url request!");
		url = uri.toString() + "/v1.0/user/bank/default/cardno";
		requestEntity = new LinkedMultiValueMap<String, String>();
		requestEntity.add("cardno", bankCard);
		requestEntity.add("type", "0");
		result = restTemplate.postForObject(url, requestEntity, String.class);
		log.info("接口/v1.0/user/bank/default/cardno--RESULT================"+result);
		try {
			jsonObject =  JSONObject.fromObject(result);
			resultObj  =  jsonObject.getJSONObject("result");
		} catch (Exception e) {
			log.error("查询银行卡信息出错");
			map.put("resp_code", "failed");
			map.put("channel_type", "jf");
			map.put("resp_message", "查询银行卡信息有误");
			return map;
		}
		String str = jsonObject.getString("result");
		if (str.equals(null) || "null".equals(str)) {
			map.put("resp_code", "failed");
			map.put("resp_message", "查询银行卡信息为null");
			return map;
		}
		
		String cardName = resultObj.getString("bankName");
		String bankname = Util.queryBankNameByBranchName(bankName);
		String cardname = Util.queryBankNameByBranchName(cardName);
		
		JFQuickRegister jfQuickRegister;
		try {
			jfQuickRegister = topupPayChannelBusiness.getJFQuickRegisterByPhoneAndBankCard(phone, cardNo);
		} catch (Exception e) {
			log.error("jfQuickRegister异常=",e);
			map.put("resp_code", "failed");
			map.put("channel_type", "jf");
			map.put("resp_message", "查询用户进件信息有误");
			return map;
		}
		if (provinceOfBank == null || "".equals(provinceOfBank) || "null".equals(provinceOfBank)) {
			provinceOfBank = "";
		}
		if (cityOfBank == null || "".equals(cityOfBank) || "null".equals(cityOfBank)) {
			cityOfBank = "";
		}
		if (bankBranchNo == null || "".equals(bankBranchNo) || "".equals(bankBranchNo)) {
			bankBranchNo = "";
		}
		if (bankBranchName == null || "".equals(bankBranchName) || "null".equals(bankBranchName)) {
			bankBranchName = "";
		}
		
		JFMQuickBindCard jfmQuickBindCard = null;
		JFQuickRegister jfQuickRegisterByRateCode2 = null;
		try {
			jfmQuickBindCard = topupPayChannelBusiness.getJFMQuickBindCard(Long.parseLong(userid), bankCard);
			jfQuickRegisterByRateCode2 = topupPayChannelBusiness.getJFQuickRegisterByRateCode2(phone, rateCode);
		} catch (Exception e) {
			log.info(e.getMessage());
		}
		if(jfQuickRegister == null){
			log.info("=========用户需要进件=========");
			//用户需要进件
			Map maps = new HashMap();
			maps.put("resp_code", "success");
			maps.put("channel_type", "jf");
			maps.put("redirect_url", ipAddress+"/v1.0/paymentchannel/topup/tojfshanglvbankinfo"+"?bankName="+URLEncoder.encode(bankname,"UTF-8")+"&bankBranchId="+bankBranchNo+
					"&bankNo="+cardNo+"&bankCard="+bankCard+"&cardName="+URLEncoder.encode(cardname,"UTF-8")+"&amount="+amount+"&ordercode="+ordercode+
					"&provinceOfBank="+URLEncoder.encode(provinceOfBank,"UTF-8")+"&cityOfBank="+URLEncoder.encode(cityOfBank,"UTF-8")+
					"&bankBranchName="+URLEncoder.encode(bankBranchName,"UTF-8")+"&cardType="+URLEncoder.encode(cardType,"UTF-8")+"&isRegister=0");
			return maps;
		} else if (jfQuickRegisterByRateCode2 == null) {
			boolean addJFMRateCode = addJFMQuickRateCode(ordercode);
			log.info("=========商户费率编号需要新增=========");
			if (addJFMRateCode) {
				if (jfmQuickBindCard == null) {
					log.info("=========用户需要绑卡=========");
					//用户需要绑卡
					Map maps = new HashMap();
					maps.put("resp_code", "success");
					maps.put("channel_type", "jf");
					maps.put("redirect_url", ipAddress+"/v1.0/paymentchannel/topup/tojfshanglvbankinfo"+"?bankName="+URLEncoder.encode(bankname,"UTF-8")+"&bankBranchId="+bankBranchNo+
							"&bankNo="+cardNo+"&bankCard="+bankCard+"&cardName="+URLEncoder.encode(cardname,"UTF-8")+"&amount="+amount+"&ordercode="+ordercode+
							"&provinceOfBank="+URLEncoder.encode(provinceOfBank,"UTF-8")+"&cityOfBank="+URLEncoder.encode(cityOfBank,"UTF-8")+
							"&bankBranchName="+URLEncoder.encode(bankBranchName,"UTF-8")+"&cardType="+URLEncoder.encode(cardType,"UTF-8")+"&isRegister=1");
					return maps;
				}
			}
		} else if (jfmQuickBindCard == null) {
			log.info("=========用户需要绑卡=========");
			//用户需要绑卡
			Map maps = new HashMap();
			maps.put("resp_code", "success");
			maps.put("channel_type", "jf");
			maps.put("redirect_url", ipAddress+"/v1.0/paymentchannel/topup/tojfshanglvbankinfo"+"?bankName="+URLEncoder.encode(bankname,"UTF-8")+"&bankBranchId="+bankBranchNo+
					"&bankNo="+cardNo+"&bankCard="+bankCard+"&cardName="+URLEncoder.encode(cardname,"UTF-8")+"&amount="+amount+"&ordercode="+ordercode+
					"&provinceOfBank="+URLEncoder.encode(provinceOfBank,"UTF-8")+"&cityOfBank="+URLEncoder.encode(cityOfBank,"UTF-8")+
					"&bankBranchName="+URLEncoder.encode(bankBranchName,"UTF-8")+"&cardType="+URLEncoder.encode(cardType,"UTF-8")+"&isRegister=1");
			return maps;
		} else {
			log.info("=========发起支付=========");
			//发起支付
			Map maps = new HashMap();
			maps.put("resp_code", "success");
			maps.put("channel_type", "jf");
			maps.put("redirect_url", ipAddress+"/v1.0/paymentchannel/topup/tojfshanglvbankinfo"+"?bankName="+URLEncoder.encode(bankname,"UTF-8")+"&bankBranchId="+bankBranchNo+
					"&bankNo="+cardNo+"&bankCard="+bankCard+"&cardName="+URLEncoder.encode(cardname,"UTF-8")+"&amount="+amount+"&ordercode="+ordercode+
					"&provinceOfBank="+URLEncoder.encode(provinceOfBank,"UTF-8")+"&cityOfBank="+URLEncoder.encode(cityOfBank,"UTF-8")+
					"&bankBranchName="+URLEncoder.encode(bankBranchName,"UTF-8")+"&cardType="+URLEncoder.encode(cardType,"UTF-8")+"&isRegister=2");
			return maps;
		}
		return null;
	}
	
	// 新增商户费率编号
	public boolean addJFMQuickRateCode(String ordercode) throws Exception {
		log.info("=========进入新增商户费率编号接口=========");
		Map map = new HashMap();
		Map<String, String> maps = new HashMap<String, String>();
		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("transactionclear", "error url request!");
		String url = uri.toString() + "/v1.0/transactionclear/payment/query/ordercode";
		MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<String, String>();
		requestEntity.add("order_code", ordercode);
		String result = restTemplate.postForObject(url, requestEntity, String.class);
		log.info("=========RESULT=========" + result);
		JSONObject jsonObject = JSONObject.fromObject(result);
		JSONObject resultObj = jsonObject.getJSONObject("result");
		String userid = resultObj.getString("userid");
		// 费率
		String rate = resultObj.getString("rate");
		// 额外费率
		String extraFee = resultObj.getString("extraFee");
		// 将额外费用变成以分为单位
		String ExtraFee = new BigDecimal(extraFee).multiply(new BigDecimal("100")).setScale(0).toString();
		
		restTemplate = new RestTemplate();
		uri = util.getServiceUrl("user", "error url request!");
		url = uri.toString() + "/v1.0/user/bank/default/userid";
		requestEntity = new LinkedMultiValueMap<String, String>();
		requestEntity.add("user_id", userid);
		result = restTemplate.postForObject(url, requestEntity, String.class);

		log.info("=========RESULT=========" + result);
		try {
			jsonObject = JSONObject.fromObject(result);
			resultObj = jsonObject.getJSONObject("result");
		} catch (Exception e) {
			log.error("查询默认结算卡出错");
		}

		String cardNo = resultObj.getString("cardNo");
		String userName = resultObj.getString("userName");
		// 身份证号 
		String idcard = resultObj.getString("idcard");
		String phone = resultObj.getString("phone");
		
		// 通过 userId查询用户进件信息
		JFQuickRegister jfQuickRegister = topupPayChannelBusiness.getJFQuickRegisterByPhoneAndBankCard(phone, cardNo);
		String platMerchantCode = jfQuickRegister.getMerchantCode();
		String CapAmount = new BigDecimal(capAmount).multiply(new BigDecimal("100")).setScale(0).toString();

		// 新增商户费率编号接口的交易代码
		String txnCode = "701004";
		String api = "/rest/api/" + txnCode;

		// 获取令牌
		PayGetToken payGetToken = new PayGetToken();
		String tokenText = payGetToken.token(Key, TokenConstants.MERCHANT_CHANGE_TOKEN, ordercode, partnerNo, JFMurl);

		JSONObject dto = new JSONObject();
		dto.put("token", tokenText);// 令牌
		dto.put("platMerchantCode", platMerchantCode);// 平台商户号
		dto.put("changeType", "3");// 变更类型
		dto.put("bankAccountNo", "");// 银行卡卡号(结算卡)
		dto.put("phoneno", "");// 银行卡预留手机号
		dto.put("bankName", "");// 银行名称
		dto.put("bankSubName", "");// 银行支行名称
		dto.put("bankCode", "");// 银行代码
		dto.put("bankAbbr", "");// 银行代号
		dto.put("bankChannelNo", "");// 支行联行号
		dto.put("bankProvince", "");// 开户行省份
		dto.put("bankCity", "");// 开户行城市
		dto.put("rateCode", rateCode);// 费率编码
		dto.put("debitRate", rate);// 借记卡费率
		dto.put("debitCapAmount", CapAmount);// 借记卡封顶
		dto.put("creditRate", rate);// 信用卡费率
		dto.put("creditCapAmount", CapAmount);// 信用卡封顶
		dto.put("withdrawDepositRate", "");// 提现费率
		dto.put("withdrawDepositSingleFee", ExtraFee);// 单笔提现手续费
		dto.put("head", payGetToken.getHead(ordercode, partnerNo, txnCode));

		String execute = payGetToken.execute(Key, JFMurl, api, dto.toString(), partnerNo, ordercode);
		log.info(execute);

		String res;
		// 返回状态码
		String respCode = null;
		String respMsg = null;
		try {
			com.alibaba.fastjson.JSONObject resJson = JSON.parseObject(execute);
			String sign = resJson.getString("signature");
			res = AES.decode(Base64.decode(resJson.getString("encryptData")), Key.substring(0, 16));
			jsonObject = JSONObject.fromObject(res);
			log.info("jsonObject=======" + jsonObject);
			JSONObject head = jsonObject.getJSONObject("head");
			log.info("head=======" + head);
			respCode = head.getString("respCode");
			log.info("respCode=====" + respCode);
			respMsg = head.getString("respMsg");
			log.info("respMsg======" + respMsg);
		} catch (Exception e) {
			log.info("亲，新增商户费率编号失败！");
		}
		
		boolean istrue = false;
		if ("000000".equals(respCode) && "success".equals(respMsg)) {
			log.info("=========商户费率编号新增成功了=========");
			jfQuickRegister.setRateCode2(rateCode);
			jfQuickRegister.setCreditRate(rate);
			jfQuickRegister.setWithdrawDepositsingleFee(extraFee);
			topupPayChannelBusiness.createJFQuickRegister(jfQuickRegister);
			istrue = true;
		} else {
			log.info("=========商户费率编号新增失败了=========");
			throw new IOException("Unexpected code");
		}
		return istrue;
	}

}
